/* global window */
/* global window */

import axios from 'axios';
import qs from 'qs';
import jsonp from 'jsonp';
import lodash from 'lodash';
import pathToRegexp from 'path-to-regexp';
import { message } from 'antd';
import { CORs } from '../config';
import AccessToken from './token';

export const token = new AccessToken();

token.loadFromDisk();

const fetch = (options) => {
  let {
    method = 'get',
    data,
    fetchType,
    url,
  } = options;

  const cloneData = lodash.cloneDeep(data);

  try {
    let domin = '';
    if (url.match(/[a-zA-z]+:\/\/[^/]*/)) {
      domin = url.match(/[a-zA-z]+:\/\/[^/]*/)[0];
      url = url.slice(domin.length);
    }
    const match = pathToRegexp.parse(url);
    url = pathToRegexp.compile(url)(data);
    for (let item of match) {
      if (item instanceof Object && item.name in cloneData) {
        delete cloneData[item.name];
      }
    }
    url = domin + url;
  } catch (e) {
    message.error(e.message);
  }

  if (fetchType === 'JSONP') {
    return new Promise((resolve, reject) => {
      jsonp(url, {
        param: `${qs.stringify(data)}&callback`,
        name: `jsonp_${new Date().getTime()}`,
        timeout: 4000,
      }, (error, result) => {
        if (error) {
          reject(error);
        }
        resolve({ statusText: 'OK', status: 200, data: result });
      });
    });
  } 
  // else if (fetchType === 'YQL') {
  //   url = `http://query.yahooapis.com/v1/public/yql?q=select * from json where url='${options.url}?${encodeURIComponent(qs.stringify(options.data))}'&format=json`;
  //   data = null;
  // }

  // infect access token to every request
  if (token.validated()) {
    axios.defaults.headers.common['U-Access-Token'] = token.valueOf();
  }

  switch (method.toLowerCase()) {
    case 'get':
      return axios.get(url, {
        params: cloneData,
      });
    case 'delete':
      return axios.delete(url, {
        data: cloneData,
      });
    case 'post':
      return axios.post(url, cloneData);
    case 'put':
      return axios.put(url, cloneData);
    case 'patch':
      return axios.patch(url, cloneData);
    default:
      return axios(options);
  }
};

function IsCodeErrorAccess (code) {

  let a = parseInt(code / 1000, 10) === 4;
  console.log(a, ' access error ');
  return a;
}

export default function request (options) {
  if (options.url && options.url.indexOf('//') > -1) {
    const origin = `${options.url.split('//')[0]}//${options.url.split('//')[1].split('/')[0]}`;
    if (window.location.origin !== origin) {
      if (CORs && CORs.indexOf(origin) > -1) {
        options.fetchType = 'CORs';
      } else {
        options.fetchType = 'JSONP';
      }
    }
  }

  return fetch(options).then((response) => {
    const { statusText, status } = response;
    let data = response.data;
    let success = true;
    if (data instanceof Array) {
      data = {
        list: data,
      };
    }

    // 判断正常 Code
    if ((data.Code && data.Code < 0) || IsCodeErrorAccess(data.Code)) {
      success = false;
    }
    // if (data.Code % 4) {

    // }


    const { Message, Code, SubCode, Data, ...otherArgs } = data;
    const newData = {
      message: Message,
      prompt: Message,
      error: Code,
      errorCode: SubCode,
      results: Data,
      ...otherArgs,
    };
    return Promise.resolve({
      success,
      message: statusText,
      statusCode: status,
      ...newData,
    });
  }).catch((error) => {
    const { response } = error;
    let msg;
    let statusCode;
    if (response && response instanceof Object) {
      const { data, statusText } = response;
      statusCode = response.status;
      msg = data.Message || statusText;
    } else {
      statusCode = 600;
      msg = error.message || '网络错误';
    }
    return Promise.reject({ 
      success: false, 
      statusCode,
      message: msg,
      prompt: msg,
      error: -500,
      errorCode: 'ERROR:FRONT:NETWORK_ERR',
      results: {},
    });
  });
}
